/*
 * Copyright (C) 2019 xuexiangjys(xuexiangjys@163.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.xuexiang.tingcibei.fragment.functions.memorizewords;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.j256.ormlite.dao.RawRowMapper;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.RawRowMapperImpl;
import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.stmt.Where;
import com.xuexiang.tingcibei.R;
import com.xuexiang.tingcibei.base.BaseFragment;
import com.xuexiang.tingcibei.base.db.entity.Words;
import com.xuexiang.xormlite.XUIDataBaseRepository;
import com.xuexiang.xormlite.db.DBService;
import com.xuexiang.xpage.annotation.Page;
import com.xuexiang.xui.widget.actionbar.TitleBar;
import com.xuexiang.xui.widget.button.switchbutton.SwitchButton;
import com.xuexiang.xui.widget.dialog.materialdialog.DialogAction;
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog;
import com.xuexiang.xui.widget.edittext.ClearEditText;
import com.xuexiang.xui.widget.spinner.materialspinner.MaterialSpinner;
import com.xuexiang.xui.widget.textview.supertextview.SuperButton;
import com.xuexiang.xutil.common.StringUtils;
import com.xuexiang.xutil.tip.ToastUtils;

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;

/**
 * @author zjh
 * @since 2024-11-5 11:23
 * 预计：新增、修改、删除、查询和重置、导入、导出、同步4级单词、同步6级单词、同步8级单词、同步学位单词、同步考研单词
 * 初步：同步
 */
@Page(name = "单词管理")
public class WordsFragment extends BaseFragment {
    /**
     * 权限请求
     */
    private static final int REQUEST_CODE_PERMISSIONS = 1;
    /**
     * 请求打开文件树
     */
    private static final int REQUEST_CODE_OPEN_DOCUMENT_TREE = 42;
    /**
     * 请求选择文件
     */
    private static final int REQUEST_CODE_PICK_FILE = 43;
    /**
     * 单词数据服务
     */
    private DBService<Words> mDBService;

    /**
     * 读取文件的单词列表
     */
    private List<Words> readWordsList = new ArrayList<>();

    /**
     * 导入按钮
     */
    @BindView(R.id.words_import)
    SuperButton wordsImport;
    @OnClick(R.id.words_import)
    public void OnWordsImportClick(View view){
        //选择文件
        pickFile();
    }

    @BindView(R.id.words_query)
    SuperButton wordsQuery;
    @OnClick(R.id.words_query)
    public void OnWordsQueryClick(View view){
        ToastUtils.toast("查询");
        /*int size = 0;
        try {
            List<Words> wordsList = mDBService.queryAll();
            if(wordsList!=null){
                size= wordsList.size();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        ToastUtils.toast("列表大小："+size);*/
        //showCustomDialog();
    }


    /**
     * TitleBar
     */
    private TitleBar mTitleBar;

    @Override
    protected TitleBar initTitle() {
        mTitleBar = super.initTitle();
        return mTitleBar;
    }


    /**
     * 布局文件
     */
    @Override
    protected int getLayoutId() {
        return R.layout.fragment_words;
    }

    /**
     * 查询对话框
     */
    private void showCustomDialog() {
        new MaterialDialog.Builder(getContext())
                .customView(R.layout.dialog_words_query, true)
                .title("单词查询")
                .positiveText(R.string.lab_submit)
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        //条件查询
                        /*View customView = dialog.getCustomView();
                        ClearEditText word = customView.findViewById(R.id.word);
                        ClearEditText wordPhonetics = customView.findViewById(R.id.wordPhonetics);
                        MaterialSpinner masterState = customView.findViewById(R.id.masterState);
                        MaterialSpinner understandState = customView.findViewById(R.id.understandState);

                        String wordString =word.getText().toString().trim();
                        String wordPhoneticsString =wordPhonetics.getText().toString().trim();
                        Object masterStateSelectedItem = masterState.getSelectedItem();
                        Object  understandSelectedItem =understandState.getSelectedItem();

                        //QueryBuilder<Words, Integer> qb = mDBService.getQueryBuilder();
                        //Where<Words, Integer> where = qb.where();

                        Map<String, Object> map=new HashMap<>(16);
                        if(!StringUtils.isEmpty(wordString)){
                            map.put("word",wordString);
                        }
                        if(!StringUtils.isEmpty(wordString)){
                            map.put("wordPhonetics",wordPhoneticsString);
                        }
                        if(masterStateSelectedItem !=null){
                            String s = masterStateSelectedItem.toString();
                            int m = (s.equals("未标记")?0:(s.equals("未掌握")?0:1));
                            map.put("masterState",m);
                        }

                        if(understandSelectedItem !=null){
                            String s = understandSelectedItem.toString();
                            int m = (s.equals("未标记")?0:(s.equals("不懂")?0:1));
                            map.put("understandState", m );
                        }

                        try {
                            List<Words> results = mDBService.queryByField(map);
                            //List<Words> words = mDBService.queryDataBySql("select * from words", null);
                            ToastUtils.toast(""+results.size());
                        } catch (SQLException e) {
                            throw new RuntimeException(e);
                        }*/

                    }
                })
                .negativeText(R.string.lab_cancel)
                .show();

    }
    /**
     * onCreate
     * @param savedInstanceState If the fragment is being re-created from
     * a previous saved state, this is the state.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDBService = XUIDataBaseRepository.getInstance().getDataBase(Words.class);

    }

    /**
     * 初始化页面
     */
    @Override
    protected void initViews() {

    }

    /**
     * （选择文件）返回页面后操作
     * @param requestCode The integer request code originally supplied to
     *                    startActivityForResult(), allowing you to identify who this
     *                    result came from.
     * @param resultCode The integer result code returned by the child activity
     *                   through its setResult().
     * @param data An Intent, which can return result data to the caller
     *               (various data can be attached to Intent "extras").
     *
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_OPEN_DOCUMENT_TREE && resultCode == Activity.RESULT_OK && data != null) {
            Uri treeUri = data.getData();
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
            //excel
            intent.setDataAndType(treeUri, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, treeUri);
            startActivityForResult(intent, REQUEST_CODE_PICK_FILE);
        } else if (requestCode == REQUEST_CODE_PICK_FILE && resultCode == Activity.RESULT_OK && data != null) {
            Uri uri = data.getData();
            try {
                readFileFromUri(uri);
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(getContext(), "Error reading file", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 读取excel
     * @param uri excel uri
     * @throws IOException
     */
    private void readFileFromUri(Uri uri) throws IOException {
        //file
        File file = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            file = getFileForUri(uri);
        }
        //先清空列表
        readWordsList.clear();
        //读excel
        FileInputStream fis = new FileInputStream(file);
        Workbook workbook = WorkbookFactory.create(fis);
        Sheet sheet = workbook.getSheetAt(0);
        for (Row row : sheet) {
            if (row.getRowNum() == 0) {
                continue; // Skip header row
            }
            Words word = new Words(
                    row.getCell(0).getStringCellValue(),
                    row.getCell(1).getStringCellValue()
            );
            readWordsList.add(word);
        }
        workbook.close();
        fis.close();
        ToastUtils.toast("列表大小："+ readWordsList.size());
        insertOrUpdateWords(readWordsList);
    }

    /**
     * 插入或更新单词
     * @param readWordsList 单词列表
     */
    private void insertOrUpdateWords(List<Words> readWordsList) {
        int insertNum = 0;
        int updateNum = 0;
        for(int i=0;i<readWordsList.size();i++){
            Words words = readWordsList.get(i);
            //查询单词
            Words exit=null;
            try {
                exit = mDBService.queryForColumnFirst("word", words.getWord());
            } catch (Exception e) {
                e.printStackTrace();
            }
            if(exit != null){
                //如果存在更新
                exit.setUpdateUser("admin");
                exit.setUpdateTime(new Date());
                try {
                    mDBService.updateData(exit);
                    updateNum++;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else{
                //不存在则插入
                try {
                    mDBService.insertData(words);
                    insertNum++;
                } catch  (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        ToastUtils.toast("更新："+updateNum+"行，插入："+insertNum+"行");
    }

    /**
     * 根据uri获取file
     * @param uri uri
     * @return File
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private File getFileForUri(Uri uri){
        String[] proj = {DocumentsContract.Document.COLUMN_DISPLAY_NAME};
        Cursor cursor = requireContext().getContentResolver().query(uri, proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(DocumentsContract.Document.COLUMN_DISPLAY_NAME);
        cursor.moveToFirst();
        String name = cursor.getString(column_index);
        cursor.close();
        File file = new File(requireContext().getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), name);
        copyUriToFile(getContext(),uri,file);
        return file;
    }

    /**
     * copyUriToFile
     * @param context context
     * @param uri uri
     * @param file file
     */
    public static void copyUriToFile(Context context, Uri uri, File file) {
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            // 使用ContentResolver打开输入流
            inputStream = context.getContentResolver().openInputStream(uri);
            if (inputStream == null) {
                throw new IOException("Failed to open input stream for URI: " + uri);
            }
            // 打开文件输出流
            outputStream = new FileOutputStream(file);
            // 创建一个缓冲区
            byte[] buffer = new byte[4 * 1024]; // 4KB缓冲区
            int bytesRead;
            // 从输入流读取数据并写入到输出流
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            Log.d("UriToFileUtil", "File copied successfully!");
        } catch (IOException e) {
            Log.e("UriToFileUtil", "Error copying URI to file", e);
        } finally {
            // 关闭流
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                Log.e("UriToFileUtil", "Error closing streams", e);
            }
        }
    }

    /**
     * 权限运行后
     * @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
     * @param permissions The requested permissions. Never null.
     * @param grantResults The grant results for the corresponding permissions
     *     which is either {@link android.content.pm.PackageManager#PERMISSION_GRANTED}
     *     or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
     *
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted, proceed to open document tree
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
            } else {
                Toast.makeText(getContext(), "Storage permission is required", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * 选择文件
     */
    private void pickFile() {
        if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(requireActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_PERMISSIONS);
        } else {
            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
        }
    }
}
